package com.spring.format.code.generation.util.file;

import java.util.List;

import com.spring.format.code.generation.constants.Constants;
import com.spring.format.code.generation.constants.FileNameEnumType;
import com.spring.format.code.generation.mybatis.po.TablePO;
import com.spring.format.code.generation.mybatis.vo.CreateFileVO;
import com.spring.format.code.generation.mybatis.vo.CreateMapperVO;
import com.spring.format.code.generation.mybatis.vo.JavaAttributeVO;
import com.spring.format.code.generation.util.FieldUtil;
import com.spring.format.code.generation.util.NameUtil;
import com.spring.format.code.generation.util.PathUtil;

/**
 * 文件生成帮助类
 * 
 * @author lenovo
 *
 */
public class CommonMyBatisFileUtil {
	private CommonMyBatisFileUtil() {

	}

	public static String content(CreateFileVO fileVO) {
		TablePO tablePO = fileVO.getTablePO();
		List<JavaAttributeVO> attrVOList = fileVO.getAttrVOList();
		// mapper的类名
		String mapperName = NameUtil.createFileName(tablePO.getTable_name(), FileNameEnumType.MAPPER_NAME);
		// 通用select sql Id
		String selectSqlId = mapperName + "SelectSql";
		// 通用where and sql Id
		String wherrAndSqlId = mapperName + "WhereAndSql";
		// //通用where or sql Id
		//String wherrOrSqlId = mapperName + "WhereOrSql";
		// po名称
		String poName = NameUtil.createFileName(tablePO.getTable_name(), FileNameEnumType.PO_NAME);
		// result Map 名称
		String resultMapName = NameUtil.createFileName(tablePO.getTable_name(), FileNameEnumType.MAPPER_MAP_NAME);

		StringBuilder attribute = new StringBuilder();
		attribute.append(head(tablePO, mapperName));

		CreateMapperVO mapperVO = createMapperVO(attrVOList, tablePO, selectSqlId, resultMapName, poName);
		// 通用sql查询
		attribute.append(commonSql(tablePO, selectSqlId, mapperVO.getSelectStr().toString()));
		// 通用 where or sql
		//attribute.append(orWhereSql(wherrOrSqlId, mapperVO.getOrStr().toString()));
		// 通用 where and sql
		attribute.append(andWhereSql(wherrAndSqlId, mapperVO.getAndStr().toString()));
		// 增加
		attribute.append(add(poName, tablePO, mapperVO.getSelectStr().toString(), mapperVO.getInsertStr().toString()));
		// 批量增加
		attribute.append(addBatch(tablePO, mapperVO.getSelectStr().toString(), mapperVO.getInsertBatchStr().toString()));
		// 根据id删除
		attribute.append(deleteById(poName, tablePO));
		// 更新信息
		attribute.append(update(poName, tablePO.getTable_name(), mapperVO.getSetStr().toString()));
		// 根据id查询
		attribute.append(queryById(poName, resultMapName, selectSqlId));
		// 查询满足条件的数量
		attribute.append(countNum(poName, tablePO.getTable_name(), wherrAndSqlId));
		// 查询分页
		attribute.append(pageList(poName, resultMapName, selectSqlId, wherrAndSqlId));
		// 查询集合
		attribute.append(queryList(poName, resultMapName, selectSqlId, wherrAndSqlId));
		// 验证数据时的查询sql
		attribute.append(queryListValidate(poName, resultMapName, selectSqlId, mapperVO.getAndStr()));
		// 更改状态
		attribute.append(editStatus(poName, tablePO.getTable_name()));
		// 批量更改状态
		attribute.append(editStatusBatch(poName, tablePO.getTable_name()));
		// //根据or条件获取唯一数据
		//attribute.append(byOrForUnique(poName, mapperVO.getOrStr().toString(), resultMapName, selectSqlId));
		// //根据or条件获取数据集合
		//attribute.append(byOr(poName, mapperVO.getOrStr().toString(), resultMapName, selectSqlId));
		// reslutMap
		attribute.append(mapperVO.getResultMapStr()).append("</mapper> \n");
		// 方法最终追加
		if(null!=mapperVO.getSpecialFieldAddition()) {
			attribute.append(mapperVO.getSpecialFieldAddition());
		}
		attribute.append(" \n ");
		return attribute.toString();

	}

	/** **/
	public static CreateMapperVO createMapperVO(List<JavaAttributeVO> attrVOList, TablePO tablePO, String selectSqlId,
			String resultMapName, String poName) {
		CreateMapperVO mapperVO = new CreateMapperVO();
		// 字段字符串
		StringBuilder selectStr = new StringBuilder();
		// insert values 字符串
		StringBuilder insertStr = new StringBuilder();
		// insertBatch values 字符串
		StringBuilder insertBatchStr = new StringBuilder();
		// where and条件
		StringBuilder andStr = new StringBuilder();
		andStr.append("<where> \n");
		// where or 条件
		StringBuilder orStr = new StringBuilder();
		orStr.append("<where> \n");
		// set 不判空，没有id字段
		StringBuilder setStr = new StringBuilder();
		setStr.append("<set> \n");
		// set 判空，没有id字段
		StringBuilder setStrByIf = new StringBuilder();
		setStrByIf.append("<set> \n");
		// 特殊字段独有方法追加
		StringBuilder specialFieldAddition = new StringBuilder();
		// mapper 字符串
		StringBuilder mapperStr = new StringBuilder();
		mapperStr.append("		<resultMap id=\"").append(resultMapName).append("\" type=\"").append(poName)
				.append("\"> \n");
		for (JavaAttributeVO attriVO : attrVOList) {
			// and 条件
			andStr.append(createIf(attriVO, " and "));
			// or 条件
			orStr.append(createIf(attriVO, " or "));
			// select 字段
			if (selectStr.length() > 0) {
				selectStr.append(",").append(attriVO.getColumnName());
				insertStr.append(",").append("#{").append(attriVO.getColumnName()).append("}");
				insertBatchStr.append(",").append("#{item.").append(attriVO.getName()).append("}");
			} else {
				selectStr.append(attriVO.getColumnName());
				insertStr.append("#{").append(attriVO.getName()).append("}");
				insertBatchStr.append("#{item.").append(attriVO.getName()).append("}");
			}
			// set 条件
			setStr.append(attriVO.getColumnName()).append("=#{").append(attriVO.getName()).append("},\n ");
			// 判断是否能更新(字段不在集合能就是能update)
			if (FieldUtil.getNotupdatefieldlist().indexOf(attriVO.getName()) < 0) {
				setStrByIf.append(setStrByIf(attriVO));
			}
			// 特殊字段，特殊方法的追加代码(如排序字段，唯一索引字段，有自己方法的字段)
			specialFieldAddition.append(specialFieldAddition(attriVO,poName,resultMapName,selectSqlId,tablePO));

			mapperStr.append(mapperResult(attriVO));
		}
		setStr.append("		</set>");
		setStrByIf.append("		</set>");
		orStr.append("			</where>");
		andStr.append("			</where>");
		mapperStr.append(associationAndCollection());
		mapperStr.append(" 		</resultMap> \n");
		mapperVO.setAndStr(andStr);
		mapperVO.setInsertStr(insertStr);
		mapperVO.setInsertBatchStr(insertBatchStr);
		//mapperVO.setOrStr(orStr);
		mapperVO.setResultMapStr(mapperStr);
		mapperVO.setSelectStr(selectStr);
		mapperVO.setSetStr(setStrByIf);
		
		return mapperVO;
	}
	/** 特殊字段需要特殊的方法追加**/
	public static String specialFieldAddition(JavaAttributeVO attriVO, String poName, String resultMapName,
			String selectSqlId, TablePO tablePO) {
		StringBuilder specialFieldAddition = new StringBuilder();
		// 判断是否有排序字段(sno,num等)
		if (FieldUtil.getOrderbyfieldlist().indexOf(attriVO.getName()) >= 0) {
			specialFieldAddition.append(
					orderByMethod(attriVO.getName(), poName, resultMapName, selectSqlId, tablePO.getTable_name()));
		}
		if (FieldUtil.getHaveselfupdatefieldlist().indexOf(attriVO.getName()) >= 0) {
			specialFieldAddition.append(
					haveSelfUpdate(attriVO.getName(), poName, tablePO.getTable_name()));
		}
		//是否有唯一索引（未完成，有唯一索引的字段可以生成自己的方法，如：id，不过字段索引属性，在数据库里面很复杂，这里就不再实现了）
		return specialFieldAddition.toString();
	}

	/** 生成 resultMap 中的 result 语句 **/
	public static String mapperResult(JavaAttributeVO attriVO) {
		StringBuilder mapperStr = new StringBuilder();
		mapperStr.append("	<result property=\"").append(attriVO.getName()).append("\" column=\"")
				.append(attriVO.getColumnName()).append("\" />\n");
		return mapperStr.toString();
	}

	/** 生成 set 中的if 语句 **/
	public static String setStrByIf(JavaAttributeVO attriVO) {
		StringBuilder setStrByIf = new StringBuilder();
		setStrByIf.append("	<if test=\"").append(attriVO.getName()).append(" !=null \"> \n ")
				.append("        			").append(attriVO.getColumnName()).append("=#{").append(attriVO.getName())
				.append("},\n ").append("	</if> \n ");
		return setStrByIf.toString();
	}

	/** 生成 and ，or 的if 语句 **/
	public static String createIf(JavaAttributeVO attriVO, String andOr) {
		StringBuilder ifStr = new StringBuilder();
		// and 条件
		ifStr.append("				<if test=\"").append(attriVO.getName()).append(" !=null \"> \n  ").append(andOr)
				.append(attriVO.getColumnName()).append(" = #{").append(attriVO.getName()).append("} \n")
				.append("				</if> \n");
		return ifStr.toString();
	}

	/** 文件头 **/
	public static String head(TablePO tablePO, String mapperName) {
		StringBuilder attribute = new StringBuilder();
		attribute.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n").append(
				"<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\"> \n")
				.append("<mapper namespace=\"")
				.append(PathUtil.createPackagePath(tablePO.getTable_name(), FileNameEnumType.MAPPER_NAME)).append(".")
				.append(mapperName).append("\"> \n");
		return attribute.toString();
	}

	/** resultMap 内嵌集合 **/
	public static String associationAndCollection() {
		StringBuilder attribute = new StringBuilder();
		attribute.append(" <!-- name like CONCAT('%', #{name}, '%') -->").append("			<!-- 单个属性数据  \n")
				.append(" 			<association property=\"bank\" javaType=\"MConsumerBankMappingEntityPO\" \n")
				.append(" 				column=\"consumer_id = id , consumer_type = consumer_nature  \" \n")
				.append("				select=\"com.sx.manage.dao.bank.IMConsumerBankMapDaoMapper.queryOne\" > \n")
				.append("  			</association> --> \n").append(" 			<!-- 集合属性数据	\n")
				.append(" 			<collection property=\"function_list\" ofType=\"MFunctionEntityPO\" 	\n")
				.append(" 				column=\"pid = id , data_status = data_status \"  select=\"get_function_list\" >	\n")
				.append(" 			</collection> --> \n");
		return attribute.toString();
	}

	/** 通用where or sql **/
	public static String orWhereSql(String wherrOrSqlId, String orStr) {
		StringBuilder attribute = new StringBuilder();
		attribute.append(" <!-- 通用where or sql --> \n").append(" <sql id=\"").append(wherrOrSqlId).append("\"> \n")
				.append(" ").append(orStr).append(" \n ").append(" </sql> \n");
		return attribute.toString();
	}
	//

	/** 通用sql查询 **/
	public static String commonSql(TablePO tablePO, String selectSqlId, String selectStr) {
		StringBuilder attribute = new StringBuilder();
		attribute.append("		<!-- 通用查询sql --> \n").append("		<sql id=\"").append(selectSqlId).append("\">\n")
				.append("			select \n ").append("      			").append(selectStr).append(" \n")
				.append(" 			from ").append(tablePO.getTable_name()).append(" \n").append("		</sql> \n");
		return attribute.toString();
	}

	/** 通用where and sql **/
	public static String andWhereSql(String wherrAndSqlId, String andStr) {
		StringBuilder attribute = new StringBuilder();
		attribute.append("		<!-- 通用where and sql --> \n").append("		<sql id=\"").append(wherrAndSqlId)
				.append("\"> \n").append("    		").append(andStr).append(" \n ").append("		</sql> \n");
		return attribute.toString();
	}

	/** 新增信息 **/
	public static String add(String poName, TablePO tablePO, String selectStr, String insertStr) {
		StringBuilder attribute = new StringBuilder();
		attribute.append("	<!-- 增加信息 --> \n ").append("	<insert id=\"")
				.append(Constants.DAO_METHOD_INSERT)
				.append("\" parameterType=\"").append(poName).append("\"> \n ").append("		insert into ")
				.append(tablePO.getTable_name()).append("\n").append("  		(").append(selectStr).append(")")
				.append("\n").append("			values \n		(").append(insertStr).append(") \n")				
				.append("<!-- 自动生成主键  \n ")
				.append(" <selectKey keyProperty=\"id\" resultType=\"java.lang.Long\" order=\"AFTER\"> \n")
				.append(" select LAST_INSERT_ID() \n ")
				.append(" </selectKey> --> \n ")
				.append("	</insert> \n");
		
		
		
		return attribute.toString();
	}
	/** 新增信息 **/
	public static String addBatch(TablePO tablePO, String selectStr, String insertStr) {
		StringBuilder attribute = new StringBuilder();
		attribute.append(" <!-- 增加信息 --> \n ")
		.append(" <insert id=\"").append(Constants.DAO_METHOD_INSERT_BATCH).append("\" parameterType=\"java.util.List\"> \n")
		.append(" insert into ").append( tablePO.getTable_name() )
		.append(" \n (").append(selectStr).append(") \n ")
		.append(" values \n ")
		.append(" <foreach collection=\"list\" item=\"item\" index=\"index\" separator=\",\"> \n ")
		.append("(").append( insertStr ).append(")")
		.append(" </foreach> \n ")
		.append(" </insert> \n ");	
		return attribute.toString();
	}
	

	/** 根据id删除 **/
	public static String deleteById(String poName, TablePO tablePO) {
		StringBuilder attribute = new StringBuilder();
		// 根据id删除
		attribute.append("	<!-- 根据id删除 --> \n").append("	<delete id=\"").append(Constants.DAO_METHOD_DELETE_BY_ID)
				.append("\" parameterType=\"").append(poName).append("\"> \n ").append("		delete from  ")
				.append(tablePO.getTable_name()).append("  	where id = #{id} \n").append("	</delete>\n");
		return attribute.toString();
	}

	/** 更新信息 **/
	public static String update(String poName, String tableName, String setStrByIf) {
		StringBuilder attribute = new StringBuilder();
		attribute.append("	<!-- 更新信息 --> \n ").append("<update id=\"").append(Constants.DAO_METHOD_UPDATE)
				.append("\" parameterType=\"").append(poName).append("\"> \n ").append("		update   ")
				.append(tableName).append(" \n").append("		").append(setStrByIf).append("\n")
				.append("  		where id = #{id} \n").append(" 	</update> \n");

		return attribute.toString();
	}

	/** 根据id查询 **/
	public static String queryById(String poName, String resultMapName, String selectSqlId) {
		StringBuilder attribute = new StringBuilder();
		attribute.append("	<!-- 根据id查询 --> \n").append("	<select id=\"").append(Constants.DAO_METHOD_QUERY_BY_ID)
				.append("\" parameterType=\"").append(poName).append("\" ").append(" 		resultMap=\"")
				.append(resultMapName).append("\" > \n ").append("			<include refid=\"").append(selectSqlId)
				.append("\"></include> \n").append("  		where id = #{id} \n").append(" 	</select>\n");

		return attribute.toString();
	}

	/** 查询满足条件的数量 **/
	public static String countNum(String poName, String tableName, String wherrAndSqlId) {
		StringBuilder attribute = new StringBuilder();
		// 查询满足条件的数量
		attribute.append("	<!-- 查询满足条件的数量 --> \n").append("	<select id=\"")
				.append(Constants.DAO_METHOD_QUERY_COUNT_NUM).append("\" parameterType=\"").append(poName).append("\" ")
				.append(" 	resultType=\"java.lang.Long\" > \n ").append("		select count(id) from \n		")
				.append(tableName).append("\n").append(" 		<include refid=\"").append(wherrAndSqlId)
				.append("\"></include> \n").append(" 	</select> \n");
		return attribute.toString();
	}

	/** 查询集合 **/
	public static String pageList(String poName, String resultMapName, String selectSqlId, String wherrAndSqlId) {
		StringBuilder attribute = new StringBuilder();
		// 查询分页
		attribute.append("	<!-- 查询分页 --> \n").append("	<select id=\"").append(Constants.DAO_METHOD_QUERY_PAGE)
				.append("\" parameterType=\"").append(poName).append("\" ").append(" 		resultMap=\"")
				.append(resultMapName).append("\" > \n ").append("		<include refid=\"").append(selectSqlId)
				.append("\"></include> \n").append(" 		<include refid=\"").append(wherrAndSqlId)
				.append("\"></include> \n").append("		order by id DESC \n")
				.append("		limit #{pageNumber},#{pageSize} \n").append(" 	</select> \n");
		return attribute.toString();
	}

	/** 查询集合 **/
	public static String queryList(String poName, String resultMapName, String selectSqlId, String wherrAndSqlId) {
		StringBuilder attribute = new StringBuilder();
		attribute.append("	<!-- 查询集合 --> \n").append("	<select id=\"").append(Constants.DAO_METHOD_QUERY_LIST)
				.append("\" parameterType=\"").append(poName).append("\" ").append(" 		resultMap=\"")
				.append(resultMapName).append("\" > \n ").append("		<include refid=\"").append(selectSqlId)
				.append("\"></include> \n").append(" 		<include refid=\"").append(wherrAndSqlId)
				.append("\"></include> \n").append("		order by id DESC \n")			
				.append(" <if test=\"pageNumber !=null and pageSize !=null\"> \n")
				.append(" limit #{pageNumber},#{pageSize} \n ")
				.append(" </if> \n ")
				.append(" 	</select> \n");
		return attribute.toString();
	}

	// 批量修改状态
	public static String editStatusBatch(String poName, String tableName) {
		StringBuilder attribute = new StringBuilder();
		attribute.append("	<!-- 批量更改状态 --> \n").append("	<update id=\"")
				.append(Constants.DAO_METHOD_EDIT_STATUS_BATCH).append("\" parameterType=\"").append(poName)
				.append("\"> \n").append("		update  ").append(tableName).append("\n").append(" 		set ")
				.append(Constants.DB_FIELD_STATUS).append("= #{")
				.append(NameUtil.subFieldName(Constants.DB_FIELD_STATUS)).append("} \n").append(" 		<where>  \n")
				.append("        id in   \n")
				.append("          <foreach collection=\"ids_\" item=\"id_\" index=\"index\" open=\"(\" separator=\",\" close=\")\" > \n")
				.append("              #{id_}\n").append("           </foreach>\n").append("      </where>\n")
				.append(" 	</update> \n");
		return attribute.toString();
	}

	/** 更新状态 **/
	public static String editStatus(String poName, String tableName) {
		StringBuilder attribute = new StringBuilder();
		attribute.append("	<!-- 更新状态  --> \n").append("	<update id=\"").append(Constants.DAO_METHOD_EDIT_STATUS)
				.append("\" parameterType=\"").append(poName).append("\"> \n").append("		update  ").append(tableName)
				.append(" set \n")
				.append(Constants.DB_FIELD_STATUS).append("= #{")
				.append(NameUtil.subFieldName(Constants.DB_FIELD_STATUS)).append("} \n")
				.append(" 		where id =  #{id}\n").append(" 	</update> \n");
		return attribute.toString();
	}

	/** 根据or条件获取唯一数据 **/
	public static String byOrForUnique(String poName, String orStr, String resultMapName, String selectSqlId) {
		// 根据or条件获取数据集合
		StringBuilder attribute = new StringBuilder();
		attribute.append("	<!-- 根据or条件获取唯一数据  --> \n").append("	<select id=\"")
				.append(Constants.DAO_METHOD_QUERY_UNIQUE_BY_OR).append("\" parameterType=\"").append(poName)
				.append("\" ").append(" 		resultMap=\"").append(resultMapName).append("\" > \n ")
				.append("		<include refid=\"").append(selectSqlId).append("\"></include> \n").append(" 	 	")
				.append(orStr).append(" \n").append(" 	</select> \n");
		return attribute.toString();
	}

	/** 根据or条件查询数据 **/
	public static String byOr(String poName, String orStr, String resultMapName, String selectSqlId) {
		// 根据or条件获取数据集合
		StringBuilder attribute = new StringBuilder();
		attribute.append("	<!-- 根据or条件获取数据集合  --> \n").append("	<select id=\"")
				.append(Constants.DAO_METHOD_QUERY_LIST_BY_OR).append("\" parameterType=\"").append(poName)
				.append("\" ").append(" 		resultMap=\"").append(resultMapName).append("\" > \n ")
				.append("		<include refid=\"").append(selectSqlId).append("\"></include> \n").append(" 	 	")
				.append(orStr).append(" \n").append("		order by id DESC \n").append(" 	</select> \n");
		return attribute.toString();
	}

	/** 查询集合验证数据重复 **/
	public static String queryListValidate(String poName, String mapName, String refid, StringBuilder andStr) {
		StringBuilder methodStr = new StringBuilder();
		methodStr.append(" <!-- 查询集合验证数据重复 --> \n ").append("<select id=\"")
				.append(Constants.DAO_METHOD_QUERY_LIST_VALIDATE).append("\" parameterType=\"").append(poName)
				.append("\" resultMap=\"").append(mapName).append("\"> \n ").append("<include refid=\"").append(refid)
				.append("\"></include> \n").append(andStr).append(" \n ").append(" order by id DESC \n ")
				.append("</select> \n ");
		return methodStr.toString();
	}
	/** 特定字段拥有自己的 修改  */
	public static String haveSelfUpdate(String fieldName, String poName, String tableName) {
		StringBuilder attribute = new StringBuilder();
		attribute.append("	<!--  --> \n ")
				.append("<update id=\"").append(NameUtil.updateName(fieldName))
				.append("\" parameterType=\"").append(poName).append("\"> \n ").append("		update   ")
				.append(tableName).append(" \n <set> ").append(fieldName).append("=#{").append(fieldName)
				.append("} \n </set> \n <where> id=#{id} </where> \n </update>");
		return attribute.toString();
	}
	/** 排序字段自己的方法 */
	public static String orderByMethod(String fieldName, String poName, String mapName, String refid,
			String tableName) {
		StringBuilder snoMethod = new StringBuilder();
		// 查询数据方法
		snoMethod.append("<!-- 根据sno变更数据-->").append("<select id=\"queryNeeChangePOBy")
				.append(NameUtil.firstCharacterToUpper(fieldName)).append("\" parameterType=\"").append(poName)
				.append("\" resultMap=\"").append(mapName).append("\"> \n ").append("<include refid=\"").append(refid)
				.append("\"></include> \n").append(" <where> \n ").append(" <if test='upOrDown==\"UP\"'> \n")
				.append(fieldName).append(" &lt; #{").append(fieldName).append("} \n").append("</if> \n ")
				.append("<if test='upOrDown==\"DOWN\"'> \n ").append(fieldName).append(" &gt; #{").append(fieldName)
				.append("} \n").append("</if> \n").append("</where> \n ").append("ORDER BY ").append(fieldName)
				.append(" \n ").append(" <if test='upOrDown==\"UP\"'> \n ").append(" DESC \n ").append(" </if> \n ")
				.append("  LIMIT 0,1; \n ").append(" </select> \n ");
		// 查询最大的sno
		snoMethod.append("<!-- 查询最大的sno --> \n ").append("<select id=\"queryMax")
				.append(NameUtil.firstCharacterToUpper(fieldName)).append("\"  resultType=\"java.lang.Integer\"> \n")
				.append("select max(").append(fieldName).append(") from ").append(tableName).append(" \n")
				.append("</select> \n ");

		return snoMethod.toString();
	}

}
